package bid

import (
	"bytes"
	"compress/gzip"
	"crypto/tls"
	"fmt"
	"github.com/valyala/fasthttp"
	"strings"
	"time"
)

type ReqResult struct {
	AdFrom     string
	Url        string
	Runtime    int64
	StatusCode int
	Data       []byte
	Error      error
	Msg        string
}

var FastClient = fasthttp.Client{
	Name:                     "THY",
	NoDefaultUserAgentHeader: true,
	MaxConnsPerHost:          5000,
	TLSConfig: &tls.Config{
		InsecureSkipVerify: true, // 忽略证书验证
	},
}

// 请求方法
func Req_fasthttp_new(adfrom string, method string, urlss string, data []byte, header map[string]string, isJson bool, isZip bool, tmax int) ReqResult {
	starttime := time.Now()
	r := ReqResult{}
	r.AdFrom = adfrom

	if isZip && data != nil {
		var dataBuffer bytes.Buffer
		zw := gzip.NewWriter(&dataBuffer)
		if _, err := zw.Write(data); err != nil {
			isZip = false
			fmt.Println("gzipError", err)
		}
		zw.Close()
		data = dataBuffer.Bytes()

	}

	r.Url = urlss
	req := fasthttp.AcquireRequest()

	req.SetRequestURI(urlss)

	req.Header.SetMethod(method)
	if data != nil {
		req.SetBody(data)
	}

	req.Header.DisableNormalizing()
	for k, v := range header {
		req.Header.Add(k, v)
	}
	if method == "POST" && isJson {
		_, ok := header["Content-Type"]
		if !ok {
			req.Header.Set("Content-Type", "application/json;charset=UTF-8")
		}
	}
	if isZip {
		req.Header.Set("Accept-Encoding", "gzip, deflate")
		req.Header.Set("Content-Encoding", "gzip")
	}

	resp := fasthttp.AcquireResponse()
	defer func() {
		// 用完需要释放资源
		fasthttp.ReleaseResponse(resp)
		fasthttp.ReleaseRequest(req)
	}()
	timeout := 300 * time.Millisecond
	if tmax > 0 {
		timeout = time.Duration(tmax) * time.Millisecond
	}
	if err := FastClient.DoTimeout(req, resp, timeout); err != nil {
		r.Error = err
		r.Runtime = time.Since(starttime).Nanoseconds() / 1e6
		r.StatusCode = 999
		return r
	}

	r.StatusCode = resp.StatusCode()
	if strings.Index(string(resp.Header.Peek("Content-Encoding")), "gzip") > -1 {
		gzipdata, err := resp.BodyGunzip()
		if err != nil {
			r.Error = err
			r.Runtime = time.Since(starttime).Nanoseconds() / 1e6
			r.StatusCode = 998
			return r
		}
		r.Data = make([]byte, len(gzipdata))
		copy(r.Data, gzipdata)
	} else {
		bs := resp.Body()
		r.Data = make([]byte, len(bs))
		copy(r.Data, bs)
	}
	r.Runtime = time.Since(starttime).Nanoseconds() / 1e6
	return r
}
